<?php
/**
 * Copyright (c) 2006, PORTALIER Julien
 *
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 *
 * @package      FeatherCMS
 * @subpackage   Members
 * @copyright    Copyright (c) 2006, Julien PORTALIER
 * @link         http://julien.portalier.com
 * @license      http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

class Filer
{
	public    $error;
	protected $mimetypes = null;
	protected $root      = WWW_ROOT;
	
	function ls($path)
	{
		$root = $this->root.$path;
		
		if (!file_exists($root))
		{
			$this->error = s_("%s: no such file or directory.", $path);
			return false;
		}
		elseif (is_file($root)) {
			$rs = $this->__fileInfo($root);
		}
		elseif (is_dir($root))
		{
			if (false !== ($dh = opendir($root)))
			{
				$rs = array();
				
				while (false !== ($file = readdir($dh)))
				{
					if ($file == '.' or $file == '..')
						continue;
					
					if (is_file($root.DS.$file))
						array_push($rs, $this->__fileInfo($root.DS.$file));
					elseif (is_dir($root.DS.$file))
					{
						array_push($rs, array(
							'name'     => $file,
							'mimetype' => 'directory',
						));
					}
				}
				closedir($dh);
			}
			else
			{
				$this->error = _("%s: can't open directory.", $path);
				return false;
			}
		}
		
		return $rs;
	}
	
	function exists($path)
	{
		return file_exists($this->root.$path);
	}
	
	function isFile($path)
	{
		return is_file($this->root.$path);
	}
	
	function isFolder($path)
	{
		return is_dir($this->root.$path);
	}
	
	function mkdir($path, $mode=0775)
	{
		$root = $this->root.$path;
		
		if (file_exists($root))
		{
			$this->error = s_('%s: file or directory already exists.', $path);
			return false;
		}
		
		return mkdir($root, $mode, true);
	}
	
	function rename($old_path, $new_path)
	{
		$old_root = $this->root.$old_path;
		$new_root = $this->root.$new_path;
		
		if (!file_exists($old_root))
		{
			$this->error = s_("%s: no such file or directory.", $old_path);
			return false;
		}
		
		if (file_exists($new_root))
		{
			$this->error = s_("Can't rename %s to %s, destination already exists.", $old_path, $new_path);
			return false;
		}
		
		if (!is_dir(dirname($new_root)))
			$this->mkdir(dirname($new_path));
		
		return rename($old_root, $new_root);
	}
	
	function rm($path)
	{
		$root = $this->root.$path;
		
		if (!file_exists($root))
		{
			$this->error = s_('%s: no such directory.', $path);
			return false;
		}
		
		return is_dir($root) ? $this->__rmdir_r($root) : unlink($root);
	}
	
	function getMimetype($fname)
	{
		if (is_null($this->mimetypes))
			$this->__loadMimetypes();
		
		$ext = f_basename($fname);
		$ext = strtolower($ext[1]);
		
		foreach($this->mimetypes as $mime => $exts)
		{
			if (in_array($ext, $exts))
				return $mime;
		}
		return null;
	}
	
	
	// internals
	
	function & __fileInfo($path)
	{
		$fname = basename($path);
		$rs = array(
			'name' => $fname,
			'size' => filesize($path),
			'mimetype' => $this->getMimetype($fname),
#			'mimetype' => 'file',
		);
		return $rs;
	}
	
	function __rmdir_r($path, $remove_empty_dir=true)
	{
		if (is_dir($path) and ($handle = opendir($path)))
		{
			while (false !== ($file = readdir($handle)))
			{
				if ($file == '.' or $file == '..')
					continue;
				
				if (is_dir($path.DS.$file))
					$this->__rmdir_r($path.DS.$file, false);
				else
				{
					if (!unlink($path.DS.$file))
						return false;
				}
			}
			closedir($handle);
			
			if (!rmdir($path))
				return false;
		}
		elseif (file_exists($path)) {
			if (!unlink($path)) return false;
		}
		
		if ($remove_empty_dir)
		{
			$files =& glob($path.'*');
			if (empty($files) and !rmdir($path))
				return false;
		}
		
		return true;
	}
	
	protected function __loadMimetypes()
	{
		$this->mimetypes = array();
		$lines = file(APP.'config'.DS.'mime.types');
		
		foreach($lines as $buf)
		{
			$buf = trim($buf);
			if (empty($buf) or strpos($buf, '#') === 0)
				continue;
			
			preg_match('|^([^\s]+?)\s+(.+)$|', $buf, $type);
			
			if (empty($type))
				continue;
			
			$this->mimetypes[$type[1]] = explode(' ', $type[2]);
		}
	}
}
?>